class Scheduler {
  constructor(size) {
    this.queue = []
    this.count = 0
    this.size = size
  }
  run(fn, ...args){
    return new Promise((resolve, reject)=>{
      this.queue.push({fn, args, resolve, reject})
      const next = () => {
        if(this.count < this.size && this.queue.length) {
          this.count++
          const {fn, args, resolve, reject} = this.queue.shift()
          fn(...args).then(resolve,reject).finally(()=>{
            this.count--
            next()
          })
        }
      }
      next()
    })
  }
}
const _scheduel = new Scheduler(2);
const timer = (time) => new Promise(resolve => {
  setTimeout(resolve,time);
})
const addTask = (time, order) => {
  _scheduel.run(() => timer(time).then(() => console.log(order)), order)
}
addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4') //2 3 1 4


class Scheduel{
  constructor(size) {
    this.size = size;
    this.queue = []
    this.count = 0
  }
  add(fn) {
    return new Promise((resolve, reject)=>{
      this.queue.push({fn, resolve, reject})
      this.run()
    })
  }
  run() {
    if(this.count<this.size && this.queue.length) {
      const {fn, resolve, reject} = this.queue.shift()
      this.count++
      fn().then(resolve, reject).finally(()=>{
        this.count--
        this.run()
      })
    }
  }
}


const scheduel = new Scheduel(2);
// 开始执行输出 i start 结束执行输出 i finish
const asyncTask = (i) => {
  return new Promise((resolve, reject) => {
    console.log(`${i} start`)
    setTimeout(() => {
      console.log(`${i} finish`)
      resolve()
    }, i*1000)
  })
}
for(let i=1;i<=5;i++) {
  scheduel.add(()=>asyncTask(i))
}